package common

import (
	"fmt"
	"log"
	"sync"
)

type AllocSlice struct {
	lock    sync.Mutex
	idx     uint64
	sliIdx  []uint64
	sliData []interface{}
	maxNum  uint64
}

func (my *AllocSlice) Init(num uint64) {
	my.sliData = make([]interface{}, num, num)
	my.sliIdx = make([]uint64, 0)
	// fmt.Println(len(my.sliData), len(my.sliIdx))
	my.maxNum = num
}

func (my *AllocSlice) Add(p interface{}) uint64 {
	my.lock.Lock()
	// fmt.Println(my.connIdx, idx)
	var idx uint64 = 0
	idxLen := len(my.sliIdx)
	if idxLen > 0 {
		idx = my.sliIdx[idxLen-1]
		my.sliIdx = my.sliIdx[:len(my.sliIdx)-1]
	} else {
		if my.idx < my.maxNum {
			my.idx++
			idx = my.idx
		}
	}
	my.lock.Unlock()

	if idx > 0 {
		// fmt.Println(my.mapTcpConn[idx], my.mapTcpConn[idx] == nil)
		if my.sliData[idx] == nil {
			my.sliData[idx] = p
			// fmt.Printf("加入成功:%d %d\n", idx, len(my.mapTcpConn))
		} else {
			idx = 0
			log.Fatal("conn has same index")
		}
	}

	return idx
}

func (my *AllocSlice) Del(idx uint64) interface{} {
	if my.sliData[idx] != nil {
		p := my.sliData[idx]
		my.sliData[idx] = nil
		my.lock.Lock()
		my.sliIdx = append(my.sliIdx, idx)
		my.lock.Unlock()
		return p
	} else {
		log.Fatal(fmt.Sprintf("Del error %d not found", idx))
	}

	return nil
}

func (my *AllocSlice) Get(idx uint64) interface{} {
	return my.sliData[idx]
}
